package com.revealreader.client;

import java.util.HashMap;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

public class Categories extends Composite implements ClickHandler {
	public static final String CATEGORY_URL = "/catalog/categories.php";

	private final Tree categoryTree = new Tree();

	public Categories() {
		categoryTree.setAnimationEnabled(true);
		categoryTree.setSize("100%", "100%");

		initWidget(categoryTree);

		update();
	}

	private final native JsArray<Category> asArrayOfCategories(String json) /*-{
		return eval(json);
	}-*/;

	public void update() {
		RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, CATEGORY_URL);

		try {
			builder.sendRequest(null, new RequestCallback() {
				public void onError(Request request, Throwable exception) {
					Window.alert("unable to get stuff from the server");
				}

				public void onResponseReceived(Request request, Response response) {
					if (200 == response.getStatusCode()) {
						updateTree(asArrayOfCategories(response.getText()));
					} else {
						Window.alert("Couldn't retrieve JSON (" + response.getStatusText() + ")");
					}
				}
			});
		} catch (RequestException e) {
			Window.alert("Couldn't retrieve JSON: " + e.getMessage());
			e.printStackTrace();
		}
	}

	public void updateTree(JsArray<Category> inCategories) {
		HashMap<String, TreeItem> itemHash = new HashMap<String, TreeItem>();

		for (int i = 0; i < inCategories.length(); i++) {
			Category category = inCategories.get(i);

			TreeItem item = new TreeItem();
			{
				item.setText(category.getName());
				item.setUserObject(category);

				itemHash.put(category.getID(), item);
			}
		}

		for (TreeItem item : itemHash.values()) {
			Category category = (Category) item.getUserObject();

			if (category.getParent() != null) {
				TreeItem parent = itemHash.get(category.getParent());

				if (parent != null) {
					parent.addItem(item);
				}
			} else {
				categoryTree.addItem(item);
			}
		}
	}

	@Override
	public void onClick(ClickEvent event) {
		// TODO Auto-generated method stub

	}

	public static class Category extends JavaScriptObject {
		protected Category() {
		}

		public final native String getID() /*-{
			return this.category_id
		}-*/;

		public final native String getName() /*-{
			return this.category_name
		}-*/;

		public final native String getParent() /*-{
			return this.parent_category_id
		}-*/;
	}
}
